package org.vectrics.recruiter.struts.tag;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;

import org.apache.ecs.html.A;
import org.apache.log4j.Category;
import org.vectrics.SystemException;
import org.vectrics.common.db.DataUtils;
import org.vectrics.common.html.BorderTable;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.html.TextHelper;
import org.vectrics.common.util.StringUtils;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.job.Job;
import org.vectrics.recruiter.job.JobCandidate;
import org.vectrics.recruiter.user.CandidateInfo;
import org.vectrics.recruiter.user.Interview;
import org.vectrics.struts.VectricsTagSupport;
import org.vectrics.user.ContactInfo;
import org.vectrics.user.Person;

public class JobCandidateTag extends VectricsTagSupport {
    public static final long serialVersionUID = 923451351;

    static private Category log = Category.getInstance(JobCandidateTag.class);

    static public String NEW_INTERVIEW_ACTION = "/admin/jobs/candidate/interview/edit.do";

    private String jobId = null;

    private String userId = null;

    private String contextPath = null;

    private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm a");

    public JobCandidateTag() {
        super();
    }

    @Override
    protected String getContextPath() {
        return contextPath;
    }

    @Override
    public String makeStartTag() {
        StringBuffer html = new StringBuffer();
        try {
            if (log.isDebugEnabled()) {
                log.debug("doStartTag() called: jobId = " + getJobId() + "  userId = " + getUserId());
            }

            // Properties formProperties = new Properties();
            // Properties invalidProperties = new Properties();
            HttpServletRequest request = (HttpServletRequest) super.pageContext.getRequest();
            contextPath = request.getContextPath();

            // HttpSession session = super.pageContext.getSession();
            String jobCandidateId = request.getParameter("jobCandidateId");
            if (StringUtils.isNullOrBlank(jobCandidateId) == true) {
                jobCandidateId = (String) request.getAttribute("jobCandidateId");
            }
            if (StringUtils.isNullOrBlank(jobCandidateId) == false) {
                JobCandidate jobCandidate = RecruitServiceLocator.getJobProvider().findJobCandidateById(
                        new Long(jobCandidateId));
                setJobId(jobCandidate.getJob().getId().toString());
                setUserId(jobCandidate.getCandidate().getPerson().getId().toString());
            }

            if (getJobId() == null) {
                log.error("Error - jobId not specified");
                throw new JspException("JobId attribute not specified");
            } else {
                log.debug("doStartTag() finding job...");

                Job job = null;

                try {
                    log.debug("Clear the cache, so we can get a new job object attached to this session that will lazy load the jobCandidates");
                    // ThreadProperties.getSession().clear();
                    job = RecruitServiceLocator.getJobProvider().findJob(new Long(getJobId()));
                } catch (Exception de) {
                    log.error("DataException finding job", de);
                    throw new JspException("DataException finding Job", de);
                }

                if (job == null) {
                    log.error("Job not found, jobId = " + getJobId());
                    throw new JspException("Count not find job, id = " + getJobId());
                } else {
                    log.debug("found job");
                }

                Person person = null;
                CandidateInfo candidate = null;

                if (getUserId() != null) {
                    log.info("doStartTag() finding person: " + getUserId());

                    person = CoreServiceLocator.getPersonService().findPersonById(new Long(getUserId()));
                    candidate = RecruitServiceLocator.getRecruitUserService().findCandidateInfo(person);
                    if (candidate == null)
                        throw new SystemException("Unexpected condition, candidate is null, person id = "
                                + person.getId());
                } else {
                    log.error("UserId property was not set.");
                    throw new JspException("UserId property was not set.");
                }

                if (person == null) {
                    log.error("Could not find personId = " + getUserId());
                    throw new JspException("Could not find userId = " + getUserId());
                }

                log.debug("doStartTag() finding job canidate...");
                JobCandidate jobCandidate = job.findJobCandidate(candidate);

                if (jobCandidate == null)
                    throw new JspException("Person is not a candidate for the job. job = " + job.getId()
                            + "  PersonId = " + person.getId());
                else {
                    log.debug("doStartTag() found job candidate");
                }

                html.append("<h2>Candidate Information</h2>");
                log.debug("doStartTag() - creating candidate info display...");

                Table table = new Table();
                table.setWidth(400);
                addFieldRow(table, "Job", job.getTitle());
                addFieldRow(table, "Candidate Name", person.getName());
                addFieldRow(table, "Canditate " + this.getPhrase("prompt.primary.email"), person.getContactInfo()
                        .getEmail());

                ContactInfo contact = person.getContactInfo();
                String homePhone = "&nbsp;";
                if (StringUtils.isNullOrBlank(contact.getHomePhone().getNumber()) == false) {
                    homePhone = contact.getHomePhone().getFormattedNumber();
                }
                addFieldRow(table, "Candidate " + this.getPhrase("prompt.phone.home"), homePhone);

                String mobilePhone = "&nbsp;";
                if (StringUtils.isNullOrBlank(contact.getCellPhone().getNumber()) == false) {
                    homePhone = contact.getCellPhone().getFormattedNumber();
                }
                addFieldRow(table, "Candidate " + this.getPhrase("prompt.mobile.phone"), mobilePhone);
                addFieldRow(table, this.getPhrase("prompt.candidate.strength"), jobCandidate.getStrength().toString());
                addFieldRow(table, this.getPhrase("phrase.candidate.status"), jobCandidate.getCurrentStatus()
                        .getStatusType().getDescription());
                addFieldRow(table, this.getPhrase("phrase.candidate.status.reason"),
                        this.getPhrase(jobCandidate.getCurrentStatus().getJobCandidateStatusReasonType().getName()));

                if (CoreServiceLocator.getConfiguration().getDebugDisplay()) {
                    addFieldRow(table, this.getPhrase("phrase.jobcandidate.id"), jobCandidate.getId().toString());
                    addFieldRow(table, this.getPhrase("phrase.job.id"), jobCandidate.getJob().getId().toString());
                    addFieldRow(table, this.getPhrase("phrase.person.id"), jobCandidate.getCandidate().getPerson()
                            .getId().toString());
                    addFieldRow(table, this.getPhrase("phrase.candidate.info.id"), jobCandidate.getCandidate().getId()
                            .toString());
                }

                if (jobCandidate.getSource() != null) {
                    addFieldRow(table, this.getPhrase("phrase.candidate.source"), jobCandidate.getSource().getName());
                } else {
                    addFieldRow(table, this.getPhrase("phrase.candidate.source"), this.getPhrase("phrase.not.given"));
                }

                String resumeDesc = "";
                if (jobCandidate.getResume() == null) {
                    Collection resumes = jobCandidate.getCandidate().getResumes();
                    resumes = DataUtils.removeVoided(resumes);
                    if (log.isDebugEnabled()) {
                        log.debug("Found resumes for candidate, count = " + resumes.size());
                    }
                    if (resumes.size() > 0) {
                        resumeDesc = this.getPhrase("phrase.jobcandidate.resumes.for.person");
                    } else {
                        resumeDesc = this.getPhrase("phrase.jobcandidate.no.resumes.for.person");
                    }
                } else {
                    resumeDesc = this.getPhrase("phrase.jobcandidate.resume.for.jobcandidate");
                }
                addFieldRow(table, this.getPhrase("phrase.job.candidate.resume.summary"), resumeDesc);

                String coverLetterDesc = this.getPhrase("phrase.no.cover.letter");
                if (jobCandidate.hasCoverLetter()) {
                    coverLetterDesc = this.getPhrase("phrase.cover.letter.submitted");
                }
                addFieldRow(table, this.getPhrase("prompt.job.candidate.cover.letter"), coverLetterDesc);

                table.addRow();
                html.append(table.toString());
                html.append("<br><br>");

                log.debug("doStartTag() - adding interview table...");
                html.append(makeInterviewTable(jobCandidate).toString());
                html.append("<br>");
            }

            log.debug("doStartTag() - writing output...");

        } catch (Exception e) {
            log.error("Exception in doStartTag()", e);
            throw new SystemException("Exception in doStartTag()", e);
        }

        return html.toString();
    }

    protected void addFieldRow(final Table table, final String caption, final String value) {
        Row row = table.addRow();
        Cell cell = row.addCell();
        cell.addElement(TextHelper.getFont("stdFont", caption));

        cell = row.addCell();
        cell.addElement(TextHelper.getFont("stdFont", "&nbsp"));

        cell = row.addCell();
        cell.setWidth(180);
        cell.setClass("fieldTableBg");
        cell.addElement(TextHelper.getFont("stdFont", value));
    }

    private Table makeInterviewTable(final JobCandidate jobCandidate) {
        log.debug("makeInterviewTable() called");

        Table table = new BorderTable();
        table.setWidth("100%");

        Row hdrRow = table.addRow();
        hdrRow.setDefaultBgImage(getContextPath() + "/site-graphics/tbl_hdr.gif");

        Cell hdrCell = hdrRow.addCell();
        hdrCell.addElement(TextHelper.getFont("tableHdrFont", "Interviews"));

        log.debug("makeInterviewTable() - getting interview iterator");

        Iterator iter = RecruitServiceLocator.getJobProvider().findJobCandidateInterviews(jobCandidate).iterator();

        if (iter.hasNext()) {
            log.debug("makeInterviewTable() - candidate has interviews");

            while (iter.hasNext()) {
                log.debug("makeInterviewTable() - getting next interview for displaying in row");

                Interview interview = (Interview) iter.next();
                addInterviewToTable(table, interview, jobCandidate);

            }
        } else {
            log.debug("makeInterviewTable() - no interviews");

            Row dataRow = table.addRow();
            Cell dataCell = dataRow.addCell();
            dataCell.setColSpan(4);
            dataCell.addElement(TextHelper.getFont("subFont", this.getPhrase("phrase.no.interviews")));
        }
        return table;
    }

    private void addInterviewToTable(final Table table, final Interview interview, final JobCandidate jobCandidate) {
        if (log.isDebugEnabled()) {
            log.debug("makeInterviewTable() - interview date = " + interview.getDateStart());
            log.debug("makeInterviewTable() - interview description = " + interview.getDescription());
            log.debug("makeInterviewTable() - interview result summary = " + interview.getStatusType().getName());
        }

        Row dataRow = table.addRow();
        Cell cell = dataRow.addCell();

        Table interviewTable = new Table();
        interviewTable.setWidth("100%");
        cell.addElement(interviewTable);

        Row row = interviewTable.addRow();
        Cell descCell = row.addCell();

        // descCell.setClass("formBg1");
        descCell.setColSpan(2);
        if(interview.getInterviewInstance() != null){
        	descCell.addElement(TextHelper.getFont("subFont", "<b>" + interview.getInterviewInstance().getDescription() + "</b>"));
        }else{
        	descCell.addElement(TextHelper.getFont("subFont", "<b>" + interview.getDescription() + "</b>"));
        }
        
        row = interviewTable.addRow();

        Cell leftCell = row.addCell();
        leftCell.setWidth(290);
        Table leftTable = new Table();
        leftTable.setWidth("100%");
        leftCell.addElement(leftTable);

        Cell rightCell = row.addCell();
        rightCell.setWidth(290);
        Table rightTable = new Table();
        rightTable.setWidth("100%");
        rightCell.addElement(rightTable);

        log.debug("makeInterviewTable() - displaying interview date");

        Row detailRow = leftTable.addRow();
        Cell detailCell = detailRow.addCell();
        detailCell.setClass("formBg1");

        if (interview.getDateStart() == null) {
            log.debug("makeInterviewTable - date is null");
            detailCell.addElement(TextHelper.getFont("subFont", "<b>Date</b><br>NotGiven"));
        } else {
            log.debug("makeInterviewTable - showing interview date");
            detailCell.addElement(TextHelper.getFont("subFont",
                    "<b>Date</b><br>" + dateFormat.format(interview.getDateStart())));
        }

        detailRow = leftTable.addRow();
        detailCell = detailRow.addCell();
        detailCell.setClass("formBg1");
        log.debug("makeInterviewTable() - displaying interviewer");

        String interviewerStr = "";

        if (interview.getLeadPerson() != null) {
            interviewerStr = interview.getLeadPerson().getName();
        }

        if (interviewerStr == null || interviewerStr.trim().length() <= 0) {
            interviewerStr = "Not Specified";
        }

        detailCell.addElement(TextHelper.getFont("subFont", "<b>Interviewer</b><br>" + interviewerStr));

        detailRow = rightTable.addRow();
        detailCell = detailRow.addCell();
        detailCell.setClass("formBg1");
        log.debug("makeInterviewTable() - displaying result summary");

        String resultStr = "";
        if (interview.getResultType() != null) {
            resultStr = "<br>" + this.getPhrase(interview.getResultType().getDescriptionCode());
        }
        detailCell.addElement(TextHelper.getFont("subFont", "<b>Outcome Summary</b><br>"
                + interview.getStatusType().getName() + resultStr));

        detailRow = rightTable.addRow();
        detailCell = detailRow.addCell();
        detailCell.setClass("formBg2");
        log.debug("makeInterviewTable() - displaying link to interview detail");

        if (jobCandidate.getCandidate() == null)
            throw new SystemException("JobCandidate object missing candidate");

        A link = new A();
        link.setClass("subLink");
        String href = getContextPath() + "/admin/jobs/candidate/interview/edit.do?id=" + interview.getId() + "&userId="
                + jobCandidate.getCandidate().getPerson().getId() + "&companyId="
                + jobCandidate.getJob().getCompany().getId();

        if (interview.getJob() != null) {
            href += "&jobId=" + jobCandidate.getJob().getId();
        }
        if (interview.getLeadPerson() != null) {
            href += "&interviewerId=" + interview.getLeadPerson().getId();
        }
        link.setHref(href);
        link.addElement("edit");
        detailCell.addElement(link);

        detailRow = rightTable.addRow();
        detailCell = detailRow.addCell();
        detailCell.setClass("formBg2");
        log.debug("makeInterviewTable() - displaying link to interview detail");
        link = new A();
        link.setClass("subLink");
        link.setHref(getContextPath() + "/admin/jobs/candidate/interview/remove.do?id=" + interview.getId() + "&jobId="
                + jobCandidate.getJob().getId() + "&userId=" + jobCandidate.getCandidate().getPerson().getId()
                + "&jobCandidateId=" + jobCandidate.getId());
        link.addElement("remove");
        detailCell.addElement(link);
    }

    /**
     * @return
     */
    public String getJobId() {
        return jobId;
    }

    /**
     * @param jobId
     */
    public void setJobId(final String jobId) {
        this.jobId = jobId;
    }

    /**
     * @return
     */
    public String getUserId() {
        return userId;
    }

    /**
     * @param userId
     */
    public void setUserId(final String userId) {
        this.userId = userId;
    }
}
